package mmo.Core;

import java.util.ArrayList;
import java.util.List;
import org.getspout.spoutapi.gui.Container;
import org.getspout.spoutapi.gui.ContainerType;
import org.getspout.spoutapi.gui.GenericWidget;
import org.getspout.spoutapi.gui.RenderPriority;
import org.getspout.spoutapi.gui.Screen;
import org.getspout.spoutapi.gui.Widget;
import org.getspout.spoutapi.gui.WidgetType;

public class GenericContainer extends GenericWidget implements Container {

	protected List<Widget> children = new ArrayList<Widget>();
	protected ContainerType type = ContainerType.VERTICAL;

	public GenericContainer() {
	}

	@Override
	public Container addChild(Widget child) {
		return insertChild(-1, child);
	}

	@Override
	public Container insertChild(int index, Widget child) {
		if (index < 0 || index > this.children.size()) {
			this.children.add(child);
		} else {
			this.children.add(index, child);
		}
		child.setContainer(this);
		child.shiftXPos(super.getX());
		child.shiftYPos(super.getY());
		child.setAnchor(super.getAnchor());
		if (this.screen != null) {
			this.screen.attachWidget(this.plugin, child);
		}
		return this;
	}

	@Override
	public Container addChildren(Widget... children) {
		for (Widget child : children) {
			this.insertChild(-1, child);
		}
		return this;
	}

	@Override
	public Widget[] getChildren() {
		Widget[] list = new Widget[children.size()];
		children.toArray(list);
		return list;
	}

	@Override
	public void setDirty(boolean dirty) {
		super.setDirty(dirty);
		for (Widget widget : children) {
			widget.setDirty(dirty);
		}
	}

	@Override
	public Container setVisible(boolean enable) {
		super.setVisible(enable);
		for (Widget widget : children) {
			widget.setVisible(enable);
		}
		return this;
	}

	@Override
	public Container setPriority(RenderPriority priority) {
		super.setPriority(priority);
		for (Widget widget : children) {
			widget.setPriority(priority);
		}
		return this;
	}

	@Override
	public WidgetType getType() {
		return WidgetType.Container;
	}

	@Override
	public Widget setX(int pos) {
		int delta = pos - super.getX();
		super.setX(pos);
		for (Widget widget : children) {
			widget.shiftXPos(delta);
		}
		return this;
	}

	@Override
	public Widget setY(int pos) {
		int delta = pos - super.getY();
		super.setY(pos);
		for (Widget widget : children) {
			widget.shiftYPos(delta);
		}
		return this;
	}

	@Override
	public void render() {
	}

	@Override
	public Container removeChild(Widget child) {
		children.remove(child);
		child.setContainer(null);
		child.shiftXPos(-super.getX()); // Put it back where it was outside the container
		child.shiftYPos(-super.getY()); // Put it back where it was outside the container
		if (this.screen != null) {
			this.screen.removeWidget(child);
		}
		return this;
	}
	
	@Override
	public Container setScreen(Screen screen) {
		for (Widget child : children) {
			if (screen != null) {
				screen.attachWidget(this.plugin, child);
			} else if (this.screen != null) {
				this.screen.removeWidget(child);
			}
		}
		super.setScreen(screen);
		return this;
	}

	@Override
	public Container setHeight(int height) {
		super.setHeight(height);
		this.updateLayout();
		return this;
	}

	@Override
	public Container setWidth(int width) {
		super.setWidth(width);
		this.updateLayout();
		return this;
	}

	@Override
	public Container setLayout(ContainerType type) {
		this.type = type;
		return this;
	}

	@Override
	public ContainerType getLayout() {
		return type;
	}

	@Override
	public Container updateLayout() {
		if (getWidth() > 0 && getHeight() > 0 && !children.isEmpty()) {
			int totalwidth = getWidth(), totalheight = getHeight(), vcount = 0, hcount = 0;
			for (Widget widget : children) {
				switch (type) {
					case VERTICAL:
						if (widget.isFixed()) {
							totalheight -= widget.getHeight() + (widget.getMargin() * 2);
						} else {
							totalheight -= widget.getMargin() * 2;
							vcount++;
						}
						break;
					case HORIZONTAL:
						if (widget.isFixed()) {
							totalwidth -= widget.getWidth() + (widget.getMargin() * 2);
						} else {
							totalwidth -= widget.getMargin() * 2;
							hcount++;
						}
						break;
				}
			}
			int left = super.getX(), top = super.getY();
			int newwidth = totalwidth / Math.max(1, hcount), newheight = totalheight / Math.max(1, vcount);
			for (Widget widget : children) {
				int extra = widget.getMargin();
				if (widget.getY() + extra != top) {
					widget.setY(top + extra);
					widget.setDirty(true);
				}
				if (widget.getX() + extra != left) {
					widget.setX(left + extra);
					widget.setDirty(true);
				}
				extra *= 2;
				if (!widget.isFixed()) {
					if (widget.getHeight() - extra != newheight) {
						widget.setHeight(newheight - extra);
						widget.setDirty(true);
					}
					if (widget.getWidth() - extra != newwidth) {
						widget.setWidth(newwidth - extra);
						widget.setDirty(true);
					}
				}
				if (widget instanceof Container) {
					((Container)widget).updateLayout();
				}
				switch (type) {
					case VERTICAL:
						top += widget.getHeight() + extra;
						break;
					case HORIZONTAL:
						left += widget.getWidth() + extra;
						break;
				}
			}
		}
		return this;
	}
}